package com.lzyyj.gmis.base.service;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.lzyyj.common.ProxyWrapper;
import com.lzyyj.gmis.base.model.IUser;
import com.lzyyj.gmis.base.model.UserVo;

/**
 * 基本用户管理服务，支持一个或多个用户类型
 * @author Lzyyj
 *
 * @param <T>
 * @param <PK>
 */
@SuppressWarnings("serial")
public class UserService<T, PK extends Serializable> extends BaseService<T, PK> implements IUserService<T, PK>,IInitNeeded {
	
	private static final Log log = LogFactory.getLog(UserService.class);
	
	private String loginNameFieldName = "loginName";
	
	private Map<String, IUserService<Object, Serializable>> userServiceMap;
	
	/**
	 * session 中当前用户 key
	 */
	private String currentUserKey = "CurrentUser";

	public String getCurrentUserKey() {
		return currentUserKey;
	}

	public void setCurrentUserKey(String currentUserKey) {
		this.currentUserKey = currentUserKey;
	}
	
	private int endId = 0;
	private Map<PK, T> userCache = new HashMap<PK, T>();
	private Map<String, T> loginNameCache = new HashMap<String, T>();
	
	@Override
	public T login(String loginName, String password) throws Exception {
		Object loginUser = null;
		
		if(loginName!=null){
			if (loginNameCache.containsKey(loginName.toLowerCase())){
				loginUser = loginNameCache.get(loginName.toLowerCase());
				IUser user = ProxyWrapper.wrap(IUser.class, loginUser);
				if (!password.equals(user.getPassword())){
					loginUser = null;
				}
			}else{
				// 是否有多种可登录用户对象
				if (userServiceMap!=null&&userServiceMap.size()>0){
					for(Entry<String,IUserService<Object, Serializable>> entry: userServiceMap.entrySet()){
						IUserService<Object, Serializable> userService = entry.getValue();
						Object u = userService.login(loginName, password);
						if (u!=null){
							IUser user = ProxyWrapper.wrap(IUser.class, "id,"+loginNameFieldName+":"+userService.getLoginNameFieldName()+",password,validatePassword", u);
							if (user.validatePassword(password)){
								Map<String, Object> u1 = new HashMap<String, Object>();
								u1.put(entry.getKey(), u);
								loginUser = u1;
								break;
							}else{
								break;
							}
						}
					}
				}else{
					if (getBaseDao()==null){
						log.warn("还未配置UserDao");
						if (password.equals(loginName)){
							loginUser = new UserVo(loginName, password);
						}else{
							loginUser = null;
						}
					}else{
						T user;
						try {
							user = useBaseDao().findUniqueBy(loginNameFieldName, loginName);
						} catch (Exception e) {
							user = null;
						}
						if (user!=null){
							IUser u1 = ProxyWrapper.wrap(IUser.class, user);
							if (u1.validatePassword(password)){
								loginUser = user;
							}
						}else{
							loginUser = null;
						}
					}
				}
			}
		}
		
		return (T)loginUser;
	}
	
	/**
	 * 注销指定用户
	 */
	@Override
	public void logout(T user) {
		if(user==null){
			// 注销当前用户
		}else{
			// 注销指定用户
			// 先检查权限，仅拥有用户管理权限的用户，才能使用，并且只能注销其管理范围内的用户
		}
	}

	@Override
	public T getCurrentUser() {
		T currentUser = null;
		
		Map<String, Object> map = getSystemService().getThreadLocalMap(false);
		if (map!=null&&map.containsKey(getCurrentUserKey())){
			currentUser = (T)map.get(getCurrentUserKey());
		}
		
		return currentUser;
	}

	public String getIdName() {
		return loginNameFieldName;
	}

	public void setIdName(String idName) {
		this.loginNameFieldName = idName;
	}

	@Override
	public void init() {
		userServiceMap = new HashMap<String, IUserService<Object, Serializable>>();
		Map<String, IUserService> map = getSystemService().getServiceMap(IUserService.class);
		if (map!=null){
			for(Entry<String, IUserService> entry:map.entrySet()){
				IUserService<Object, Serializable> userService = entry.getValue();
				if (!userService.equals(this)&&userService.getClass()!=null){
					userServiceMap.put(entry.getKey(), userService);
				}
			}
		}
	}
	
	public UserService(){
		super();
	}

	public UserService(Class<T> entityClass){
		super(entityClass);
	}

	@Override
	public void stop() {
		// TODO Auto-generated method stub
		
	}

	public String getLoginNameFieldName() {
		return loginNameFieldName;
	}

	public void setLoginNameFieldName(String loginNameFieldName) {
		this.loginNameFieldName = loginNameFieldName;
	}

	@Override
	public Map<String, Object> getThreadLocalMap(boolean create) {
		Map<String, Object> threadLocalMap = null;
		
		if (getSystemService()!=null){
			threadLocalMap = getSystemService().getThreadLocalMap(create);
		}
		
		return threadLocalMap;
	}

}
